package com.gilight.base.service.impl;

import com.gilight.base.base.BusinessException;
import com.gilight.base.common.BzdmConstant;
import com.gilight.base.common.RoleStatus;
import com.gilight.base.dao.SysRoleMapper;
import com.gilight.base.dto.RoleDto;
import com.gilight.base.model.SysRole;
import com.gilight.base.model.SysUser;
import com.gilight.base.service.SysRoleService;
import com.gilight.base.util.ShiroUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SysRoleServiceImpl implements SysRoleService {
    @Autowired
    private SysRoleMapper roleMapper;


    public List<SysRole> selectByRoleName(String roleName) {
        return roleMapper.selectByRoleName(roleName);
    }


    @Override
    public PageInfo findList(RoleDto roleDto) {
        Map<String, Object> map = new HashMap();
        if (StringUtils.isNotEmpty(roleDto.getRoleName())) {
            map.put("roleName", "%"+roleDto.getRoleName()+"%");
        }
        map.put("status",roleDto.getStatus());
        PageHelper.startPage(roleDto.getPageNum(), roleDto.getPageSize());
        List<SysRole> list = roleMapper.findList(map);
        PageInfo pageInfo = new PageInfo(list);
        return pageInfo;
    }

    public List<SysRole> all() {
        Map<String, Object> map = new HashMap();
        map.put("status", RoleStatus.ENABLE);
        List<SysRole> list = roleMapper.findList(map);
        return list;
    }

    @Override
    public void add(SysRole role) {
        if (StringUtils.isEmpty(role.getRoleName())) {
            throw new BusinessException("角色名不能为空");
        }
        roleMapper.insert(role);
    }

    @Override
    public void edit(SysRole role) {
        if (StringUtils.isEmpty(role.getRoleName())) {
            throw new BusinessException("角色名不能为空");
        }
        roleMapper.updateByPrimaryKeySelective(role);
    }

    @Transactional
    @Override
    public void delete(Long id) {
        if (id==1) {
            throw new BusinessException("该角色不可删除");
        }
        roleMapper.deleteByPrimaryKey(id);
        roleMapper.delUserRoleByRoleId(id);
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        SysRole role = new SysRole();
        role.setId(id);
        role.setStatus(status);
        roleMapper.updateByPrimaryKeySelective(role);
    }

    @Override
    public List<Map<String, Object>> findAllPermission(Long roleId,String appKey) {
        List<Map<String, Object>> list = roleMapper.findAllPermission(roleId,appKey);
        List<Map<String, Object>> resultList = packageTree(list, -1L);
        return resultList;
    }

    private List<Map<String, Object>> packageTree(List<Map<String, Object>> list, Long parentId) {
        if (CollectionUtils.isEmpty(list)){
            return null;
        }

        List<Map<String, Object>> children = list.stream().filter(map -> parentId.equals(map.get("parent_id")))
                .collect(Collectors.toList());
        for (Map<String, Object> map : children) {
            Long id = (Long)map.get("id");
            map.put("children", packageTree(list, id));
        }
        return children;
    }

    @Override
    public List<Map<String, Object>> allPermission(String appKey) {
        List<Map<String, Object>> list = roleMapper.allPermission(appKey);
        List<Map<String, Object>> resultList = packageTree(list, -1L);
        return resultList;
    }

    @Transactional
    @Override
    @CacheEvict(value = BzdmConstant.REDIS_LOADMENU, allEntries = true)
    public void assign(Long id, List<Long> permissionIdList,String appKey) {
        roleMapper.delRolePermissionByRoleId(id,appKey);
        roleMapper.insertBatchRolePermission(id, permissionIdList,appKey);
    }
    @Transactional
    @Override
    public void assignButton(Long id, List<Long> permissionIdList,Long menuId) {
        List<Long> permissionIds=  roleMapper.selectButtonPermissionIdByRoleId(id,menuId);
        String appKey = roleMapper.getAppKeyByMenuId(menuId);
        if(permissionIds.size()>0){
            roleMapper.delRoleButtonPermissionByRoleId(id,permissionIds,appKey);
        }
        if(null!=permissionIdList&&permissionIdList.size()>0){
            roleMapper.insertBatchRolePermission(id, permissionIdList,appKey);
        }
    }

    @Override
    public List<Map<String, Object>> findAllButtonPermission(Long roleId) {

        return roleMapper.findAllButtonPermission(roleId);
    }

    @Override
    public Long selectDefaultRoleByUserId(Long userId) {
        SysRole sysRole= roleMapper.selectDefaultRoleByUserId(userId);
        return sysRole != null? sysRole.getId(): null;
    }


    @Override
    public List<SysRole> selectByUserId(Long userId) {
        return roleMapper.selectByUserId(userId);
    }
    /**
     * 获取当前登录人的角色ID：暂时不考虑多角色
     * @return 当前登录人的角色ID
     */
    /**
     * 角色授予菜单的数据规则
     * @param id 角色ID
     * @param permissionId 资源菜单ID
     * @param dataRuleIds 数据规则ID：90,30,40
     */
    @Transactional
    @Override
    public void assignRoleDataRule(Long id, Long permissionId,String dataRuleIds) {
        if(id != null && permissionId != null){
            if(dataRuleIds == null) dataRuleIds = "";
            Map params = new HashMap();
            params.put("roleId",id);
            params.put("permissionId",permissionId);
            params.put("dataRuleIds",dataRuleIds);
            roleMapper.assignRoleDataRule(params);
        }
    }

    @Override
    public List<Map<String, Object>> getUserListByRoleId(Map<String, Object> map ) {
        List<Map<String, Object>> list= roleMapper. getUserListByRoleId(map);
        return list;
    }

    @Override
    public void deleteRole(Long roleId) {
        //删除角色
        roleMapper.deleteByPrimaryKey(roleId);
        // 删除用户角色
        roleMapper.deleteSysUserRoleData(roleId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUserRoleBatch(Map<String, Object> mapParam) {
        List userIds = (List) mapParam.get("userList");
        Long roleId = Long.parseLong(mapParam.get("roleId").toString());
        for (int i = 0; i < userIds.size(); i++) {
            Long userId = Long.parseLong(userIds.get(i).toString());
            Map<String, Object> map=new HashMap<>();
            map.put("roleId", mapParam.get("roleId"));
            map.put("userId",userId);

            List<SysRole> roles = roleMapper.selectByUserId(userId);
            Integer isDefault = 0;
            boolean save;
            if (CollectionUtils.isNotEmpty(roles)) {
                long exist = roles.stream().filter(role -> roleId.equals(role.getId())).count();
                save = exist<=0 ? true :false;
            } else {
                isDefault = 1;
                save = true;
            }
            if (save) {
                map.put("isDefault", isDefault);
            }
            roleMapper.addUserRoleBatch(map);
        }
    }

    @Override
    public void deleteUserRole(Long roleId, Long userId) {
        roleMapper.deleteUserRole(roleId,userId);
    }

    @Override
    public List<SysRole> findRoleList() {
        Map<String,Object> map=new HashMap<>();
        map.put("status",1);
        List<SysRole> list = roleMapper.findList(map);
        return list;
    }
}
